/* HackerPort driver for Linux
 * version 0.7.2 date 2007-05-04
 * part of the hacker port project - http[s]://stefan.schuermans.info/hackerport/
 * Copyright (C) 2003-2007 Stefan Schuermans <stefan@schuermans.info>
 * Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
 */



#ifndef INC_hkp_drv
#define INC_hkp_drv



#include <linux/ioctl.h>
#include <linux/usb.h>



//*** structures for actions

//type of action
enum t_hkp_drv_act_type
{
  hkp_drv_act_out_a, hkp_drv_act_out_b, hkp_drv_act_out_all,
  hkp_drv_act_in_a, hkp_drv_act_in_b, hkp_drv_act_in_all,
  hkp_drv_act_burst_out_a, hkp_drv_act_burst_out_b, hkp_drv_act_burst_out_all,
  hkp_drv_act_burst_out_in_a, hkp_drv_act_burst_out_in_b, hkp_drv_act_burst_out_in_all,
  hkp_drv_act_pwm_a, hkp_drv_act_pwm_b, hkp_drv_act_pwm_all, hkp_drv_act_pwm_speed,
  hkp_drv_act_analog_a, hkp_drv_act_analog_b, hkp_drv_act_analog_c, hkp_drv_act_analog_d, hkp_drv_act_analog_e, hkp_drv_act_analog_all,
  hkp_drv_act_i2c_speed, hkp_drv_act_i2c_start, hkp_drv_act_i2c_write, hkp_drv_act_i2c_read, hkp_drv_act_i2c_ack, hkp_drv_act_i2c_nak, hkp_drv_act_i2c_stop,
  hkp_drv_act_pic_set, hkp_drv_act_pic_get, hkp_drv_act_pic_out, hkp_drv_act_pic_in,
  hkp_drv_act_jtag_set, hkp_drv_act_jtag_get,
} et_hkp_drv_type;

//output
struct t_hkp_drv_act_out
{
  unsigned char x;
} st_hkp_drv_act_out;
struct t_hkp_drv_act_out_all
{
  unsigned char a, b;
} st_hkp_drv_act_out_all;

//input
struct t_hkp_drv_act_in
{
  unsigned char x;
} st_hkp_drv_act_in;
struct t_hkp_drv_act_in_all
{
  unsigned char a, b;
} st_hkp_drv_act_in_all;

//burst output
struct t_hkp_drv_act_burst_out
{
  struct { unsigned char x; } steps[16];
} st_hkp_drv_act_burst_out;
struct t_hkp_drv_act_burst_out_all
{
  struct { unsigned char a, b; } steps[16];
} st_hkp_drv_act_burst_out_all;

//burst output with input
struct t_hkp_drv_act_burst_out_in
{
  struct { unsigned char o_x, i_x; } steps[16];
} st_hkp_drv_act_burst_out_in;
struct t_hkp_drv_act_burst_out_in_all
{
  struct { unsigned char o_a, o_b, i_a, i_b; } steps[16];
} st_hkp_drv_act_burst_out_in_all;

//PWM output
struct t_hkp_drv_act_pwm
{
  unsigned short x;
} st_hkp_drv_act_pwm;
struct t_hkp_drv_act_pwm_all
{
  unsigned short a, b;
} st_hkp_drv_act_pwm_all;
struct t_hkp_drv_act_pwm_speed
{
  unsigned char freq; //frequency in 250 Hz steps
} st_hkp_drv_act_pwm_speed;

//analog input
struct t_hkp_drv_act_analog
{
  unsigned short x;
} st_hkp_drv_act_analog;
struct t_hkp_drv_act_analog_all
{
  unsigned short a, b, c, d, e;
} st_hkp_drv_act_analog_all;

//i2c
struct t_hkp_drv_act_i2c_speed
{
  unsigned char bit_time; //time for a single bit in 100 ns steps
} st_hkp_drv_act_i2c_speed;
struct t_hkp_drv_act_i2c_write
{
  unsigned char data; //data to write
  char acked; //if data was acked (1) or not (0)
} st_hkp_drv_act_i2c_write;
struct t_hkp_drv_act_i2c_read
{
  unsigned char data; //data read
} st_hkp_drv_act_i2c_read;

//pic programming interface
#define HKP_DRV_PIC_VPP_0V 0
#define HKP_DRV_PIC_VPP_13V 1
#define HKP_DRV_PIC_VPP_OPEN 2
#define HKP_DRV_PIC_VPP_NO_CHANGE -1
#define HKP_DRV_PIC_PGC_LOW 0
#define HKP_DRV_PIC_PGC_HIGH 1
#define HKP_DRV_PIC_PGC_NO_CHANGE -1
#define HKP_DRV_PIC_PGD_LOW 0
#define HKP_DRV_PIC_PGD_HIGH 1
#define HKP_DRV_PIC_PGD_OPEN 2
#define HKP_DRV_PIC_PGD_NO_CHANGE -1
struct t_hkp_drv_act_pic_set
{
  char vpp, pgc, pgd; //state for output pins
} st_hkp_drv_act_pic_set;
struct t_hkp_drv_act_pic_get
{
  char pgd; //state of input pin
} st_hkp_drv_act_pic_get;
struct t_hkp_drv_act_pic_out_in
{
  unsigned char cnt; //number of bits to write or to read (0..16) 
  unsigned short data; //the data to write or the data read (LSB first, right aligned)
} st_hkp_drv_act_pic_out_in;

//jtag master port
#define HKP_DRV_JTAG_LOW 0
#define HKP_DRV_JTAG_HIGH 1
#define HKP_DRV_JTAG_NO_CHANGE -1
struct t_hkp_drv_act_jtag_set
{
  char ntrst, tms, tck, tdi; //state for output pins
} st_hkp_drv_act_jtag_set;
struct t_hkp_drv_act_jtag_get
{
  char tdo; //state of input pin
} st_hkp_drv_act_jtag_get;

//an action
union t_hkp_drv_act_data
{
  struct t_hkp_drv_act_out out;
  struct t_hkp_drv_act_out_all out_all;
  struct t_hkp_drv_act_in in;
  struct t_hkp_drv_act_in_all in_all;
  struct t_hkp_drv_act_burst_out burst_out;
  struct t_hkp_drv_act_burst_out_all burst_out_all;
  struct t_hkp_drv_act_burst_out_in burst_out_in;
  struct t_hkp_drv_act_burst_out_in_all burst_out_in_all;
  struct t_hkp_drv_act_pwm pwm;
  struct t_hkp_drv_act_pwm_all pwm_all;
  struct t_hkp_drv_act_pwm_speed pwm_speed;
  struct t_hkp_drv_act_analog analog;
  struct t_hkp_drv_act_analog_all analog_all;
  struct t_hkp_drv_act_i2c_speed i2c_speed;
  struct t_hkp_drv_act_i2c_write i2c_write;
  struct t_hkp_drv_act_i2c_read i2c_read;
  struct t_hkp_drv_act_pic_set pic_set;
  struct t_hkp_drv_act_pic_get pic_get;
  struct t_hkp_drv_act_pic_out_in pic_out_in;
  struct t_hkp_drv_act_jtag_set jtag_set;
  struct t_hkp_drv_act_jtag_get jtag_get;
} ut_hkp_drv_act_data;
struct t_hkp_drv_act
{
  enum t_hkp_drv_act_type type; //the type of the action
  union t_hkp_drv_act_data data; //the data of the action
  int err_out; //error code of the output part of the action (0 if no output part)
  int err_in; //error code of the input part of the action (0 if no input part)
} st_hkp_drv_act;



//*** structures for ioctls

//version of driver
struct t_hkp_drv_ver
{
  unsigned char major, minor, revision;
  unsigned short year;
  unsigned char month, day;
} st_hkp_drv_ver;

//hardware version
struct t_hkp_drv_hw_ver
{
  unsigned char variant;
  unsigned char major, minor, revision;
  unsigned short year;
  unsigned char month, day;
} st_hkp_drv_hw_ver;

//identification
//used to name the hacker port
//i.e. to distinguish between multiple connected hacker ports
struct t_hkp_drv_id
{
  unsigned char id[16];
} st_hkp_drv_id;

//ownership of ports
//  structure members indicate ownership
//    >  0: own port / port is owned
//    == 0: do not change ownership of port
//    <  0: free port / port is not freed
struct t_hkp_drv_own
{
  char out[2]; //ownership of output ports
  char in[2]; //ownership of input ports
  char pwm[2]; //ownership of PWM outputs
  char analog[5]; //ownership of analog inputs
  char ser; //ownership of serial port
  char i2c; //ownership of i2c bus
  char pic; //ownership of pic programming interface
  char jtag; //ownership of jtag master port
} st_hkp_drv_own;

//execute an action
//see above: strcut t_hkp_drv_act

//execute multiple actions
struct t_hkp_drv_acts
{
  unsigned char cnt; //number of actions
  struct t_hkp_drv_act * p_acts; //pointer to array with <cnt> actions
} st_hkp_drv_acts;

//set baudrate of serial port
struct t_hkp_drv_ser_baud
{
  unsigned short bit_time; //time for a single bit in 100 ns steps
} st_hkp_drv_ser_baud;

//send data on serial port
struct t_hkp_drv_ser_send
{
  unsigned char len; //length of data to send (<= 64)
  unsigned char data[64]; //data to send
} st_hkp_drv_ser_send;

//receive data from serial port
struct t_hkp_drv_ser_recv
{
  unsigned char err_frame; //framing error
  unsigned char err_ov_hw; //overflow error in hardware
  unsigned char err_ov_fw; //buffer overflow error in firmware
  unsigned char err_ov_drv; //buffer overflow in driver
  unsigned char len; //length of data received
  unsigned char data[64]; //data received
} st_hkp_drv_ser_recv;




//*** ioctls

//get version of driver
#define hkp_drv_ioctl_no_ver _IOR( 0x42, 0x00, struct t_hkp_drv_ver )

//get hardware version
#define hkp_drv_ioctl_no_hw_ver _IOR( 0x42, 0x01, struct t_hkp_drv_hw_ver )

//get identification
#define hkp_drv_ioctl_no_get_id _IOR( 0x42, 0x10, struct t_hkp_drv_id )

//set identification
#define hkp_drv_ioctl_no_set_id _IOW( 0x42, 0x11, struct t_hkp_drv_id )

//own (or free) ports
//tries to own or free some ports and returns owned ports
#define hkp_drv_ioctl_no_own _IOWR( 0x42, 0x20, struct t_hkp_drv_own )

//execute an action
#define hkp_drv_ioctl_no_act _IOWR( 0x42, 0x30, struct t_hkp_drv_act )

//execute multiple actions
#define hkp_drv_ioctl_no_acts _IOWR( 0x42, 0x31, struct t_hkp_drv_acts )

//set baudrate of serial port
#define hkp_drv_ioctl_no_ser_baud _IOW( 0x42, 0x40, struct t_hkp_drv_ser_baud )

//send data on serial port
#define hkp_drv_ioctl_no_ser_send _IOW( 0x42, 0x41, struct t_hkp_drv_ser_send )

//receive data from serial port
#define hkp_drv_ioctl_no_ser_recv _IOR( 0x42, 0x42, struct t_hkp_drv_ser_recv )



#endif //#ifndef INC_hkp_drv
